#ifndef _BASE_THREAD_H_
#define _BASE_THREAD_H_

#include "Meta.AbstractTask.h"
#include "Base.MutexLocker.h"
#include "Base.Mutex.h"

#ifdef _POSIX_VERSION
#include <pthread.h>
#elif WIN32
#include "Windows.h"
#endif

namespace Maha
{
      namespace Base
      {
            using Maha::Meta::AbstractTask;

            class Thread
            {
            public:
                  
                  void Release()
                  {
                        //MutexLocker lock(mutex);
                        released = true;
                  }
            
                  bool isReleased() const
                  {
                        //MutexLocker lock(mutex);
                        return released;
                  }
            
		      explicit Thread(AbstractTask& task) : released(false), task(task.Clone())
		      {
#ifdef _POSIX_VERSION
			      pthread_create(&handle, 0, &exec, this->task);
#elif WIN32
			      LPSECURITY_ATTRIBUTES	lpThreadAttributes = 0;
			      SIZE_T dwStackSize = 0;
			      LPTHREAD_START_ROUTINE lpStartAddress = exec;
			      LPVOID lpParameter = &task;
			      DWORD dwCreationFlags = 0;
			      DWORD threadId = 0;
			
			      HANDLE handle = CreateThread(
			            lpThreadAttributes,
			            dwStackSize,
			            lpStartAddress,
			            lpParameter,
			            dwCreationFlags,
			            &threadId
			      ); 
#endif
		      }
		
		      ~Thread()
		      {
#ifdef _POSIX_VERSION
                        pthread_cancel(handle);
#elif WIN32
                        CloseHandle(handle);
#endif
                        delete task;
                  }
            private:

#ifdef _POSIX_VERSION
                  static void* exec(void* task)
                  {
                        std::cout << "exec" << std::endl;
                        static_cast<AbstractTask*>(task)->exec();
                        //MutexLocker lock(mutex);
                        //released = true;
                  }
#elif WIN32
                  static __stdcall DWORD exec(void* task)
                  {
                        static_cast<AbstractTask*>(task)->exec();
                        //MutexLocker lock(mutex);
                        //released = true;
                  }
#endif

            private:

#ifdef _POSIX_VERSION
                  pthread_t handle;
#elif WIN32
                  HANDLE handle;
#endif
                  bool released;
            
                  AbstractTask* task;
            
                  //Mutex mutex;
            };
      } // Base
} // Maha

#endif // _BASE_THREAD_H_
